﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.IO;

namespace AutomationTools
{
    public class Pagina
    {
        public string Agent { get; set; }
        public IWebProxy Proxy { get; set; }
        public Encoding CharSet { get; set; }
        public string Encoding { get; set; }
        public CookieContainer CookieContainer { get; set; }
        public bool KeepAlive { get; set; }
        public bool AllowRedirect { get; set; }
        public X509Certificate Certificate { get; set; }
        public string Uri { get; set; }
        public string ContentType { get; set; }

        public Pagina()
        {
            KeepAlive = false;
            AllowRedirect = true;
            Encoding = null;
            CharSet = System.Text.Encoding.UTF8;
            Proxy = null;
            Agent = "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.202 Safari/535.1";
            ContentType = "application/x-www-form-urlencoded";
            CookieContainer = new CookieContainer();
        }

        public Pagina(string uri)
            : this()
        {
            Uri = uri;
        }

        public void CarregarCertificado(string fileName)
        {
            Certificate = X509Certificate.CreateFromCertFile(fileName);
        }

        private HttpWebRequest CriarRequest(string uri)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
            request.AllowAutoRedirect = AllowRedirect;
            request.MaximumAutomaticRedirections = 4;
            request.MaximumResponseHeadersLength = 4;

            request.KeepAlive = KeepAlive;
            request.Proxy = Proxy;
            request.ContentType = ContentType;
            if (CookieContainer != null)
                request.CookieContainer = CookieContainer;
            if (Certificate != null)
                request.ClientCertificates.Add(Certificate);
            if (Encoding != null)
                request.TransferEncoding = Encoding;
            return request;
        }

        public string EfetuarPost()
        {
            return EfetuarPost(null);
        }

        public string EfetuarPost(ParametrosRequest parametros)
        {
            return EfetuarPost(Uri, parametros);
        }

        public string EfetuarPost(string uri, ParametrosRequest parametros)
        {
            HttpWebRequest request = CriarRequest(uri);
            request.Method = "POST";

            string strParametro = FormatarParametros(parametros);
            request.ContentLength = strParametro.Length;

            using (StreamWriter sw = new StreamWriter(request.GetRequestStream()))
            {
                sw.Write(strParametro);
            }

            using (StreamReader sr = new StreamReader(request.GetResponse().GetResponseStream(), CharSet))
            {
                return sr.ReadToEnd();
            }
        }


        public string EfetuarGet()
        {
            return EfetuarGet(null);
        }

        public string EfetuarGet(ParametrosRequest parametros)
        {
            return EfetuarGet(Uri, parametros);
        }

        public string EfetuarGet(string uri, ParametrosRequest parametros)
        {
            string strParametro = FormatarParametros(parametros);
            HttpWebRequest request = CriarRequest(uri + "?" + strParametro);
            request.Method = "GET";

            using (StreamReader sr = new StreamReader(request.GetResponse().GetResponseStream(), CharSet))
            {
                return sr.ReadToEnd();
            }
        }

        private string FormatarParametros(ParametrosRequest parametros)
        {
            StringBuilder strParametros = new StringBuilder();
            string separador = "";
            if (parametros != null)
            {
                foreach (var item in parametros)
                {
                    strParametros.Append(string.Format("{0}{1}={2}", separador, item.Name, item.Value));
                    separador = "&";
                }
            }
            return strParametros.ToString();
        }
    }

    public class ParametrosRequest : List<ParametroRequest>
    {
        public ParametrosRequest(params ParametroRequest[] parametros)
        {
            this.AddRange(parametros);
        }

        public void Add(string name, string value)
        {
            this.Add(new ParametroRequest(name, value));
        }
    }

    public class ParametroRequest
    {
        public ParametroRequest(string name, string value)
        {
            this.Name = name;
            this.Value = value;
        }

        public string Name { get; set; }
        public string Value { get; set; }
    }
}
